/*
 * Copyright 2011 Angel Sanadinov
 *
 * This file is part of VBox WMI.
 *
 * VBox WMI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VBox WMI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
 */

package Beans.Requests.MachineManagement.Components;

import Utilities.Functions;
import org.virtualbox_3_2.NetworkAdapterType;
import org.virtualbox_3_2.NetworkAttachmentType;

/**
 * This class represents the complete networking settings of a virtual machine.
 *
 * @author Angel Sanadinov
 */
public class NetworkAdapterSettings extends MachineManagementComponent
{
    private NetworkAdapterType adapterType;         //adapter type
    private NetworkAttachmentType attachmentType;   //attached network type
    private boolean adapterState;                   //adapter state
    private String MACAddress;                      //adapter MAC address
    private String attachedNetworkName;             //name of attached network
    private String externalNetworkName;             //external name for internal networks
    private boolean isCableConnected;               //cable state
    private int lineSpeed;                          //adapter line speed (in units of 1kbps)
    private int bootPriority;                       //adapter boot priority (1 is the highest)
    private NATEngineSettings natEngineSetup;       //NAT engine setup

    /**
     * Constructs a network adapter settings object with the specified data.
     *
     * @param adapterType the type of the adapter
     * @param attachmentType the type of network attachment
     * @param adapterState the state of the adapter
     * @param MACAddress the MAC address of the adapter
     * @param networkName the name of the attached network
     * @param externalName the external name of the network (only for internal networks, <code>null</code> for all others)
     * @param cableConnected the state of the adapter cable
     * @param lineSpeed the line speed of the adapter (in units of 1kbps)
     */
    public NetworkAdapterSettings(NetworkAdapterType adapterType, NetworkAttachmentType attachmentType,
                                  boolean adapterState, String MACAddress, String networkName, String externalName,
                                  boolean cableConnected, int lineSpeed)
    {
        this.adapterType = adapterType;
        this.attachmentType = attachmentType;
        this.adapterState = adapterState;
        this.MACAddress = MACAddress;
        this.attachedNetworkName = networkName;
        this.externalNetworkName = externalName;
        this.isCableConnected = cableConnected;
        this.lineSpeed = lineSpeed;
        this.bootPriority = 0;
        this.natEngineSetup = null;
    }

    /**
     * Retrieves the adapter type.
     *
     * @return the adapter type
     */
    public NetworkAdapterType getAdapterType()
    {
        return adapterType;
    }

    /**
     * Retrieves the network attachment type.
     *
     * @return the attachment type
     */
    public NetworkAttachmentType getAttachmentType()
    {
        return attachmentType;
    }

    /**
     * Retrieves the state of the adapter.
     *
     * @return <code>true</code> if the adapter is enabled or <code>false</code> if
     *         it is not enabled
     */
    public boolean getAdapterState()
    {
        return adapterState;
    }

    /**
     * Retrieves the MAC address of the adapter.
     *
     * @return the adapter MAC address
     */
    public String getMACAddress()
    {
        return MACAddress;
    }

    /**
     * Retrieves the name of the attached network.
     *
     * @return the network name
     */
    public String getAttachedNetworkName()
    {
        return attachedNetworkName;
    }

    /**
     * Retrieves the external name of the attached internal network.
     *
     * @return the network's external name, if available or <code>null</code> otherwise
     */
    public String getExternalNetworkName()
    {
        return externalNetworkName;
    }

    /**
     * Retrieves the state of the adapter's cable.
     *
     * @return <code>true</code> if the cable is connected or <code>false</code>
     *         if it is not
     */
    public boolean getIsCableConnected()
    {
        return isCableConnected;
    }

    /**
     * Retrieves the line speed of the adapter.
     *
     * @return the line speed (in units of 1kbps)
     */
    public int getLineSpeed()
    {
        return lineSpeed;
    }

    /**
     * Retrieves the boot priority of the adapter.
     *
     * @return the boot priority, if set
     */
    public int getBootPriority()
    {
        return bootPriority;
    }

    /**
     * Retrieves the NAT engine configuration of the adapter.
     *
     * @return the NAT engine configuration, if available or <code>null</code> if not
     */
    public NATEngineSettings getNatEngineSetup()
    {
        return natEngineSetup;
    }

    /**
     * Sets the boot priority of the adapter.
     *
     * @param bootPriority the boot priority
     */
    public void setBootPriority(int bootPriority)
    {
        this.bootPriority = bootPriority;
    }

    /**
     * Sets the NAT engine configuration of the adapter.
     *
     * @param natEngineSetup the NAT engine configuration
     */
    public void setNatEngineSetup(NATEngineSettings natEngineSetup)
    {
        this.natEngineSetup = natEngineSetup;
    }

    /**
     * Validates the network name, if an internal network is used.
     *
     * @return <code>true</code> if the internal network name is valid and
     *         if another network type is used or <code>false</code> if
     *         the internal network name is not valid
     */
    private boolean isAttachedNetworkNameValid()
    {
        if(attachmentType == NetworkAttachmentType.INTERNAL)
            return Functions.isUUIDValid(attachedNetworkName);
        else
            return true;
    }

    @Override
    public boolean isValid()
    {
        if(adapterType != null && attachmentType != null && lineSpeed >= 0
                && bootPriority >= 0
                && (natEngineSetup == null || natEngineSetup.isValid())
                && isAttachedNetworkNameValid())
            return true;
        else
            return false;
    }
}
